package com.yunsoft.notice.service.manager;

import com.fld.platform.redis.RedisMgrBean;
import com.yunsoft.notice.api.dto.NotifyRecordDto;
import com.yunsoft.notice.service.db.dao.NotifyRecordDao;
import com.yunsoft.notice.service.db.entity.NotifyRecord;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import com.alibaba.fastjson.JSON;
import com.fld.platform.commons.utils.EntityConverUtils;
import com.fld.platform.threadpool.monitor.ThreadPoolExecutorMonitor;

@Component
public class NotifyRecordManager implements ApplicationListener<ContextRefreshedEvent> {

    private final static Logger LOGGER = LoggerFactory.getLogger(NotifyRecordManager.class);

    private ExecutorService threadPool = ThreadPoolExecutorMonitor.newFixedThreadPool(4,"async-save-notify-record");

    private final static String JBD_NOTIFY_SERVICE_ASYNC_SAVE_RECORD_QUEUE = "JBD_NOTIFY_SERVICE_ASYNC_SAVE_RECORD_QUEUE";
    @Autowired
    private NotifyRecordDao notifyRecordDao;

    @Autowired
    private RedisMgrBean redisMgrBean;

    public List<NotifyRecordDto> findByRequestId(String requestId) {
        List<NotifyRecord> notifyRecordList = notifyRecordDao.findByRequestId(requestId);
        return EntityConverUtils.converList(notifyRecordList,NotifyRecordDto.class);
    }

    private void start() {
        LOGGER.info("[异步保存消息通知][线程启动]");

        while (true) {
            try {
                saveToDb();
                // 空闲等待
                Thread.sleep(10000);
            } catch (Exception e) {
                LOGGER.error("[异步保存消息通知][处理失败]", e);
            }
        }
    }

    private void saveToDb() {
        final List<NotifyRecord> data = new ArrayList<NotifyRecord>();
        //获取
        while (true) {
            if (data.size() >= 100) {
                break;
            }
            Object dtoStr = redisMgrBean.rpop(JBD_NOTIFY_SERVICE_ASYNC_SAVE_RECORD_QUEUE);
            if (dtoStr == null) {
                break;
            }
            try {
                NotifyRecord record = JSON.parseObject((String)dtoStr,NotifyRecord.class);
                data.add(record);
            } catch (Exception e) {
                LOGGER.error("[异步保存消息通知][JSON转换异常]",e);
            }
        }
        if (data.size() == 0) {
            return;
        }
        //
        threadPool.execute(new Runnable() {
            @Override
            public void run() {
                notifyRecordDao.saveBatch(data);
            }
        });
    }

    /**
     * spring启动完后启动
     * @param event
     */
    @Override
    public void onApplicationEvent(ContextRefreshedEvent event) {
        threadPool.execute(new Runnable() {
            @Override
            public void run() {
                start();
            }
        });
    }

    public void asyncSaveList(List<NotifyRecord> recordList) {
        if(CollectionUtils.isEmpty(recordList)) {
            return;
        }
        for (NotifyRecord record : recordList) {
            try {
                LOGGER.info("[保存消息通知]{}",record.toString());
                redisMgrBean.lpush(JBD_NOTIFY_SERVICE_ASYNC_SAVE_RECORD_QUEUE,JSON.toJSONString(record));
            } catch (Exception e) {
                notifyRecordDao.saveBatch(recordList);
            }
        }
    }

    public void asyncSave(NotifyRecord record) {
        if(record == null) {
            return;
        }
        LOGGER.info("[保存消息通知]{}",record.toString());
        try {
            redisMgrBean.lpush(JBD_NOTIFY_SERVICE_ASYNC_SAVE_RECORD_QUEUE,JSON.toJSONString(record));
        } catch (Exception e) {
            notifyRecordDao.save(record);
        }
    }
}
